package com.example.shiro;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import java.util.LinkedHashMap;


@Configuration
public class ShiroConfiguration {
    @Bean("credentialMatcher")
    public CredentialMatcher credentialMatcher() {
        return new CredentialMatcher();
    }



 /*  @Bean("hashedCredentialsMatcher")
   public HashedCredentialsMatcher hashedCredentialsMatcher() {
       HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
       //指定加密方式为MD5
       credentialsMatcher.setHashAlgorithmName("MD5");
       //加密次数
       credentialsMatcher.setHashIterations(1024);
       credentialsMatcher.setStoredCredentialsHexEncoded(true);
       return credentialsMatcher;
   }*/

   /* @Bean("authRealm")
    @DependsOn("lifecycleBeanPostProcessor")//可选
    public AuthRealm authRealm(@Qualifier("hashedCredentialsMatcher") HashedCredentialsMatcher  matcher) {
        AuthRealm authRealm = new AuthRealm();
        authRealm.setAuthorizationCachingEnabled(false);
        authRealm.setCredentialsMatcher(matcher);
        // 设置缓存在内存中
        //authRealm.setCacheManager(new MemoryConstrainedCacheManager());
        return authRealm;
    }*/
   @Bean("authRealm")
   @DependsOn("lifecycleBeanPostProcessor")//可选
   public AuthRealm authRealm(@Qualifier("credentialMatcher") CredentialMatcher  matcher) {
       AuthRealm authRealm = new AuthRealm();
       authRealm.setAuthorizationCachingEnabled(false);
       authRealm.setCredentialsMatcher(matcher);

       return authRealm;
   }

    @Bean("securityManager")
    public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm realm) {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(realm);
        return manager;
    }

    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(manager);

        // 登陆路径/login
        bean.setLoginUrl("/login");
        // 登陆成功路径/index
        bean.setSuccessUrl("/pages/index.jsp");
        // 权限不足或认证失败路径/unauthorized
        bean.setUnauthorizedUrl("/pages/unauthorized.jsp");

        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        // 需要经过身份认证才可以访问/index
        filterChainDefinitionMap.put("/index", "authc");
        // 可以匿名使用
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/loginuser", "anon");
        filterChainDefinitionMap.put("/druid/**", "anon");
        // 只有admin角色才可以访问/admin
        filterChainDefinitionMap.put("/admin", "roles[admin]");
        // 只有拿到edit权限的用户才可以访问/edit
        filterChainDefinitionMap.put("/edit", "roles[edit]");
        // 登陆后的所有角色都可以访问/**
        filterChainDefinitionMap.put("/**", "authc");
        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return bean;
    }

    @Bean
    //("authorizationAttributeSourceAdvisor")
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
            @Qualifier("securityManager") SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

    /**
     * 实现Spring的自动代理
     *
     * @return
     */
    @Bean
    //("defaultAdvisorAutoProxyCreator")
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        return creator;
    }
    /**
     * lifecycleBeanPostProcessor是负责生命周期的 , 初始化和销毁的类
     * (可选)
     */
    @Bean("lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }
}
